﻿using System.IO;
using System.Web;
using SlamCms.Common;

namespace SlamCms.SharePointServices
{
	public class SharePointDocumentService : SharePointServiceBase
	{
		private readonly HttpContextBase httpContext;

		public SharePointDocumentService(HttpContextBase httpContext)
		{
			this.httpContext = httpContext;
		}

		protected override string FolderVirtualPath
		{
			get
			{
				return "~/App_Data/Documents/";
			}
		}

		public string RetrieveUrl(string url)
		{
			var relativeUrl = "{0}".F(url);
			return relativeUrl;
		}

		public FileData Retrieve(string url, string localFileName = null)
		{
			var localFilePath = LocalFilePath(url, localFileName);

			if (this.MustDownloadFile(localFilePath))
			{
				var remoteFileUrl = RemoteFileUrl(url);
				Download(remoteFileUrl, localFilePath);
			}

			return RetrieveFileFromFileSystem(localFilePath);
		}

		public void Save(string url, Stream file)
		{
			SaveInternal(url, file);
			Invalidate(url);
		}

		public void Delete(string url)
		{
			DeleteInternal(url);
			Invalidate(url);
		}

		public void Invalidate(string url)
		{
			var localFilePath = LocalFilePath(url);

			var fileExtension = Path.GetExtension(localFilePath);
			var fileFolder = Path.GetDirectoryName(localFilePath);
			var fileName = Path.GetFileNameWithoutExtension(localFilePath);
			var pattern = fileName + "*" + fileExtension;

			var directoryInfo = new DirectoryInfo(fileFolder);

			var files = directoryInfo.GetFiles(pattern, SearchOption.AllDirectories);
			foreach (var file in files)
			{
				if (file.Extension == ".metadata")
					continue;

				UpdateMetadata(file.FullName, m => m.IsDirty = true);
			}
		}

		public void InvalidateByPattern(string pattern)
		{
			var documentsDirectory = httpContext.Server.MapPath(FolderVirtualPath);
			var directoryInfo = new DirectoryInfo(documentsDirectory);
			var files = directoryInfo.GetFiles(pattern, SearchOption.AllDirectories);
			foreach (var file in files)
			{
				if (file.Extension == ".metadata")
					continue;

				UpdateMetadata(file.FullName, m => m.IsDirty = true);
			}
		}

		protected string LocalFilePath(string url, string localFileName = null)
		{
			string localRelativePath;
			if (!localFileName.IsNullOrEmpty())
			{
				localRelativePath = localFileName.TrimStart('/');
			}
			else
			{
				url = "~/" + url.TrimStart('/');
				var directoryHash = VirtualPathUtility.GetDirectory(url).GetMD5Hash();
				var filename = VirtualPathUtility.GetFileName(url);
				localRelativePath = directoryHash + "/" + filename;
			}

			var localFilePath = httpContext.Server.MapPath(FolderVirtualPath + localRelativePath);
			return localFilePath;
		}

		protected string RemoteFileUrl(string url)
		{
			return GetAbsoluteUrl(url);
		}

	}
}